package backend;

import java.io.File;
import java.io.Reader;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException; 

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class FileIO {
	
	public FileIO() {
	}
	
	/**
	 * This methods allows the Tasks in SaveList/Undone Task List to be exported in
	 * XML file format. 
	 * 
	 * @param filename  The filename as desired by User
	 * @param SaveList  The ArrayList of Task/Undone Task List
	 * @return
	 */
	public boolean ExportXML(String filename, ArrayList<Task> SaveList) {
		int i=0;
		String ddmmyy="";
		
		try {
			 
			DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
	 
			// root elements
			Document doc = docBuilder.newDocument();
			Element rootElement = doc.createElement("Remember4Me");
			doc.appendChild(rootElement);
	 
			for(i=0; i<SaveList.size(); i++) {
				// item elements
				Element item = doc.createElement("Item");
				rootElement.appendChild(item);
				
				// Store data stored under Label
				Element Label = doc.createElement("Label");
				Label.appendChild(doc.createTextNode(SaveList.get(i).label));
				item.appendChild(Label);
					 
				// Store data stored under Task
				Element TaskDescription = doc.createElement("Task");
				TaskDescription.appendChild(doc.createTextNode(SaveList.get(i).description)); 
				item.appendChild(TaskDescription);
				
				// Store data stored under Date
				Element Date = doc.createElement("Date");
				ddmmyy = String.format("%02d",SaveList.get(i).dd)+String.format("%02d",SaveList.get(i).mm)+String.format("%02d",SaveList.get(i).yy);
				Date.appendChild(doc.createTextNode(ddmmyy));
				item.appendChild(Date);
				
				// Store data stored under Start Time
				Element StartTime = doc.createElement("StartTime");
				StartTime.appendChild(doc.createTextNode(SaveList.get(i).strStartTime));
				item.appendChild(StartTime);
			
				// Store data stored under Due Time
				Element DueTime = doc.createElement("DueTime");
				DueTime.appendChild(doc.createTextNode(SaveList.get(i).strEndTime));
				item.appendChild(DueTime);
				
				// Store data stored under Venue
				Element Venue = doc.createElement("Venue");
				Venue.appendChild(doc.createTextNode(SaveList.get(i).venue));
				item.appendChild(Venue);
				
				// Store data stored under Importance
				Element Importance = doc.createElement("Importance");
				if(SaveList.get(i).hasImportance)
					Importance.appendChild(doc.createTextNode("YES"));
				else
					Importance.appendChild(doc.createTextNode("NO"));
				item.appendChild(Importance);
				
				// Store data stored under State
				Element State = doc.createElement("State"); 
				State.appendChild(doc.createTextNode(SaveList.get(i).curStateStr));
				item.appendChild(State);
				
				// Store data stored under Alarm
				Element Alarm = doc.createElement("Alarm");
				if(SaveList.get(i).alarm)
					Alarm.appendChild(doc.createTextNode("YES"));
				else
					Alarm.appendChild(doc.createTextNode("NO"));
				item.appendChild(Alarm);
			}
			
			// write the content into XML file
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(new File(filename));
	 
			transformer.transform(source, result);
	 
		} catch (ParserConfigurationException pce) {
			pce.printStackTrace();
		} catch (TransformerException tfe) {
			tfe.printStackTrace();
		}
		
		return true;
	}
	
	/** This method allows Tasks to be imported via the correctly-entered filename.
	 * 
	 * @param filename  The filename as entered by the User: ie, filename.xml
	 * @return
	 */
	public ArrayList<Task> ImportXML(String filename) {
		
		NodeList textList;
		NodeList ElementsTag;
		Element ElementMarker;
		ArrayList<Task> ImportedTasks = new ArrayList<Task>(999);;
		Task task;
		char[] temp;
		int dd=0, mm=0, yy=0;
		String ddmmyy="-", StartTimeString="-", DueTimeString="-", StoreLabel="-", StoreTask="-", StoreVenue="-", State="-";
		boolean Importance=false, Alarm=false; 
		
		try {

            DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
            Document doc = docBuilder.parse (new File(filename));

            // normalize text representation
            doc.getDocumentElement ().normalize ();
            System.out.println ("Root element of the XML file is " + doc.getDocumentElement().getNodeName());

            NodeList listOfTasks = doc.getElementsByTagName("Item");
            int totalTasks = listOfTasks.getLength();
            System.out.println("Total no of Item : " + totalTasks);

            for(int s=0; s<listOfTasks.getLength() ; s++){

                Node firstTaskNode = listOfTasks.item(s);
                if(firstTaskNode.getNodeType() == Node.ELEMENT_NODE){

                    Element firstTaskElement = (Element)firstTaskNode;

                    //Read data stored under Label
                    ElementsTag = firstTaskElement.getElementsByTagName("Label");
                    ElementMarker = (Element)ElementsTag.item(0);
                    textList = ElementMarker.getChildNodes();
                    StoreLabel = ((Node)textList.item(0)).getNodeValue().trim();
                    System.out.println("Label : " + ((Node)textList.item(0)).getNodeValue().trim());

                    //Read data stored under Task
                    ElementsTag = firstTaskElement.getElementsByTagName("Task");
                    ElementMarker = (Element)ElementsTag.item(0);
                    textList = ElementMarker.getChildNodes();
                    StoreTask = ((Node)textList.item(0)).getNodeValue().trim();
                    System.out.println("Task : " + ((Node)textList.item(0)).getNodeValue().trim());

                    //Read data stored under Date
                    ElementsTag = firstTaskElement.getElementsByTagName("Date");
                    ElementMarker = (Element)ElementsTag.item(0);
                    textList = ElementMarker.getChildNodes();
                    ddmmyy = ((Node)textList.item(0)).getNodeValue().trim();
            		temp = ((Node)textList.item(0)).getNodeValue().trim().toCharArray();
            		yy = ((temp[4]-48)*10) + (temp[5]-48);
            		mm = ((temp[2]-48)*10) + (temp[3]-48);
            		dd = ((temp[0]-48)*10) + (temp[1]-48);
                    System.out.println("Date : " + ((Node)textList.item(0)).getNodeValue().trim());
                    
                    //Read data stored under Start Time
                    ElementsTag = firstTaskElement.getElementsByTagName("StartTime");
                    ElementMarker = (Element)ElementsTag.item(0);
                    textList = ElementMarker.getChildNodes();
                    StartTimeString = ((Node)textList.item(0)).getNodeValue().trim();
                    System.out.println("Start Time : " + ((Node)textList.item(0)).getNodeValue().trim());
                    
                    //Read data stored under Due Time
                    ElementsTag = firstTaskElement.getElementsByTagName("DueTime");
                    ElementMarker = (Element)ElementsTag.item(0);
                    textList = ElementMarker.getChildNodes();
                    DueTimeString = ((Node)textList.item(0)).getNodeValue().trim();
                    System.out.println("Due Time : " + ((Node)textList.item(0)).getNodeValue().trim());
                 
                    //Read data stored under Venue
                    ElementsTag = firstTaskElement.getElementsByTagName("Venue");
                    ElementMarker = (Element)ElementsTag.item(0);
                    textList = ElementMarker.getChildNodes();
                    StoreVenue = ((Node)textList.item(0)).getNodeValue().trim();
                    System.out.println("Venue : " + ((Node)textList.item(0)).getNodeValue().trim());
                 
                    //Read data stored under Importance
                    ElementsTag = firstTaskElement.getElementsByTagName("Importance");
                    ElementMarker = (Element)ElementsTag.item(0);
                    textList = ElementMarker.getChildNodes();
                    if(((Node)textList.item(0)).getNodeValue().trim().equals("YES"))
                    	Importance = true;
                    System.out.println("Importance : " + ((Node)textList.item(0)).getNodeValue().trim());
                 
                    //Read data stored under State 
                    ElementsTag = firstTaskElement.getElementsByTagName("State");
                    ElementMarker = (Element)ElementsTag.item(0);
                    textList = ElementMarker.getChildNodes();
                    State = ((Node)textList.item(0)).getNodeValue().trim();
                    System.out.println("State : " + ((Node)textList.item(0)).getNodeValue().trim());

                    //Read data stored under Alarm
                    ElementsTag = firstTaskElement.getElementsByTagName("Alarm");
                    ElementMarker = (Element)ElementsTag.item(0);
                    textList = ElementMarker.getChildNodes();
                    if(((Node)textList.item(0)).getNodeValue().trim().equals("YES"))
                    	Alarm = true;
                    System.out.println("Alarm : " + ((Node)textList.item(0)).getNodeValue().trim());

                    task = new Task(dd, mm, yy, StartTimeString, DueTimeString, StoreLabel, Importance, StoreTask, StoreVenue, Alarm);
                   
                    task.setState(State);
                    ImportedTasks.add(task);
                }
            }

        }catch (SAXParseException err) {
        System.out.println ("** Parsing error" + ", line " + err.getLineNumber () + ", uri " + err.getSystemId ());
        System.out.println(" " + err.getMessage ());

        }catch (SAXException e) {
        Exception x = e.getException ();
        ((x == null) ? e : x).printStackTrace ();

        }catch (Throwable t) {
        t.printStackTrace ();
        }	
		
		return ImportedTasks;
	}
}
